
#include<math.h>
#include<pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>

#include "ManageRoute.h"
#include "Constant.h"

int routerTable[256];
int routerEtx[256];


int routerID;
pthread_mutex_t router_mutex;

void del_router(int dst);
void add_router(int dst, int gw);

void ManageRoute_init(){
	printf("ManageRoute_init\n");
	pthread_mutex_init(&router_mutex, NULL);
	int i=0;
	for(i=0; i<256;i++){
		routerEtx[i]=65536;
	}

/*
	//----------------------gate way--------------------------------
	system("iptables -F");
	system("iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE");
	system("echo 1 >> /proc/sys/net/ipv4/ip_forward");
	routerTable[255]=255; //indicate internet addr
	routerEtx[255]=10;
	routerTTL[255]=1000000;
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*/

}

void ManageRoute(){
    int i;
    i=0;
}


int getRouterInfo(char *router){
	pthread_mutex_lock( &router_mutex);
	int len=0;
	int i=0;

	router[len++]=routerID%256;

	for(i=0;i<256;i++){
		if( routerEtx[i]<65536 ){
			router[len++]=i;  //dst
			router[len++]=routerTable[i];  //next hop
			router[len++]=routerEtx[i]/256;
			router[len++]=routerEtx[i]%256;
		}
	}
	pthread_mutex_unlock( &router_mutex);
	return len;
}


void updateRouter(int ID, char* router, int len, float* neighbourRR){

    int etx;
    int i;
    //int flag[256];
    //int routerChangeFlag=0;

    if( ((len-1)%4) !=0 ){
		printf("updataRouter--paremeter error!\n");
		return;
	}

    etx=routerEtx[ID];

    printf("updateRouter---ID=%d, router[0]=%d,routerID=%d, len=%d\n",ID,router[0]&0x00FF, routerID, len);

    pthread_mutex_lock( &router_mutex);
    if( (router[0]&0x00FF)>routerID ){
		routerID=router[0]&0x00FF;
		//qingkong shuo you de lu you;
		for(i=0;i<256;i++){
            if(routerEtx[i]<65536 || routerTable[i]!=0){
						    routerEtx[i]=65536;
								routerTable[i]=0;
				        del_router(i);
			}
		}

		for(i=0;i<256;i++){
			if(neighbourRR[i]>0.01){
				routerEtx[i]=1/neighbourRR[i];
				routerTable[i]=i;
			}
		}

	}
	else if( (router[0]&0x00FF)==routerID ){

		if(etx==65536){
			pthread_mutex_unlock( &router_mutex);
		    return;
	    }

	    int dst=0;
	    int dst_etx=0;
	    int next_hop=0;



	    for(i=1; i<len; i+=4){//update the router which next hop is ID
            dst= 0x00ff & router[i];
            next_hop=0x00ff & router[i+1];

            if(dst==HOSTID || next_hop==HOSTID)
                continue;

            dst_etx=(0x00ff & router[i+2])*256+(0x00ff & router[i+3]);


            if( routerTable[dst]==ID ){
			    routerEtx[dst]=etx+dst_etx;
		    }
		    else{
                if(routerEtx[dst]>etx+dst_etx){
			        routerEtx[dst]=etx+dst_etx;
			        routerTable[dst]=ID;

			        del_router(dst);
			        add_router(dst,ID);
		    }
			}
		}
	}
	pthread_mutex_unlock( &router_mutex);
}


//--------------------------------del or add OS's routeTable--------------------------
void del_router(int dst){
	if(dst==255){
		while(system("route del default")==0);
		return;
	}
	char cmd[50];
	memset(cmd,0,sizeof(cmd));
	strcpy(cmd,"route del ");
	int i, j;
	int len=strlen(cmd);
	for(i=0,j=0;j<3;i++){
	    cmd[len++]=HOSTIP[i];
	    if(HOSTIP[i]=='.')
	        j++;
	}
	sprintf(cmd+len,"%d",dst);
        printf("%s\n",cmd);
	while(system(cmd)==0);
}

void add_router(int dst, int gw){
	char cmd[50];
	memset(cmd,0,sizeof(cmd));
	int i, j,len;
	if(dst==255){
		strcpy(cmd,"route add default gw ");
		len=strlen(cmd);
		for(i=0,j=0;j<3;i++){
			cmd[len++]=HOSTIP[i];
			if(HOSTIP[i]=='.')
			    j++;
		}
	}
	else{
	    strcpy(cmd,"route add ");
		len=strlen(cmd);
		for(i=0,j=0;j<3;i++){
	    	cmd[len++]=HOSTIP[i];
	    	if(HOSTIP[i]=='.')
	       	 j++;
		}
		sprintf(cmd+len,"%d gw ",dst);
		len=strlen(cmd);
		for(i=0,j=0;j<3;i++){
			cmd[len++]=HOSTIP[i];
			if(HOSTIP[i]=='.')
	        	j++;
		}
	}
	sprintf(cmd+len,"%d",gw);
    printf("%s\n",cmd);
	system(cmd);
}
